package com.atguigu.gulimall.authserver.controller;

import com.alibaba.fastjson.TypeReference;
import com.atguigu.common.constant.AuthServerConstant;
import com.atguigu.common.exception.BizCodeEnume;
import com.atguigu.common.utils.R;
import com.atguigu.common.vo.MemberResponseVo;
import com.atguigu.gulimall.authserver.feign.MemberFeignService;
import com.atguigu.gulimall.authserver.feign.ThirdPartyFeignService;
import com.atguigu.gulimall.authserver.vo.UserLoginInfoVo;
import com.atguigu.gulimall.authserver.vo.UserRegisterVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import javax.servlet.http.HttpSession;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Controller
@Slf4j
public class LoginController {
    @Autowired
    ThirdPartyFeignService thirdPartyFeignService;

    @Autowired
    StringRedisTemplate stringRedisTemplate;

    @Autowired
    MemberFeignService memberFeignService;
    @GetMapping("/login.html")
    public String toLoginPage(HttpSession session){
        if (session.getAttribute(AuthServerConstant.LOGIN_USER)!=null){
            return "redirect:http://gulimall.com";
        }
        return "login";
    }
    @ResponseBody
    @GetMapping("/sms/sendcode")
    public R sendCode(@RequestParam("phone") String phone) {
        String redisCode= stringRedisTemplate.opsForValue().get(AuthServerConstant.SMS_CODE_CACHE_PREFOX+phone);
        if(null != redisCode && redisCode.length() > 0){
            long CuuTime = Long.parseLong(redisCode.split("_")[1]);
            if(System.currentTimeMillis() - CuuTime < 60 * 1000){ // 60s
                return R.error(BizCodeEnume.SMS_CODE_EXCEPTION.getCode(), BizCodeEnume.SMS_CODE_EXCEPTION.getMsg());
            }
        }

        //2.验证码再次校验。存redis
        String code = UUID.randomUUID().toString().substring(0,5);
        String redis_code = code + "_" + System.currentTimeMillis();
        //redis缓存验证码,同一个手机号在60s内再次发送验证码
        stringRedisTemplate.opsForValue().set(AuthServerConstant.SMS_CODE_CACHE_PREFOX+phone,redis_code,10, TimeUnit.MINUTES);

        //1.接口防刷
        thirdPartyFeignService.sendCode(phone,code);
        return R.ok();
    }

    @PostMapping("/register")
    public String register(@Validated UserRegisterVo registerVo,
                           BindingResult result,
                           RedirectAttributes redirectAttributes) {
        Map<String, String> errors = new HashMap<>();
        if (result.hasErrors()) {
            //1.1 如果校验不通过，则封装校验结果
            result.getFieldErrors().forEach(item -> {
                // 获取错误的属性名和错误信息
                errors.put(item.getField(), item.getDefaultMessage());
                //1.2 将错误信息封装到session中

            });
            redirectAttributes.addFlashAttribute("errors", errors);
            return "redirect:http://auth.gulimall.com/reg.html";
        }else{
            String pageCode = registerVo.getCode();
            String saveRedisCode=stringRedisTemplate.opsForValue().get(AuthServerConstant.SMS_CODE_CACHE_PREFOX+registerVo.getPhone());
            if(pageCode.equals(saveRedisCode.split("_")[0]) && saveRedisCode !=null){
                //如果验证码校验通过则调用远程服务进行数据存储
                //1.验证成功删除原有的验证码
                stringRedisTemplate.delete(AuthServerConstant.SMS_CODE_CACHE_PREFOX+registerVo.getPhone());
                //2.1.2 远程调用会员服务注册
                R r = memberFeignService.register(registerVo);

                if (r.getCode() == 0) {
                    //调用成功，重定向登录页
                    return "redirect:http://auth.gulimall.com/login.html";
                }else {
                    //调用失败，返回注册页并显示错误信息
                    String msg = (String) r.get("msg");
                    errors.put("msg", msg);
                    redirectAttributes.addFlashAttribute("errors", errors);
                    return "redirect:http://auth.gulimall.com/reg.html";
                }
            }else {
                errors.put("code","验证码错误");
                return "redirect:http://auth.gulimall.com/reg.html";
            }
        }
    }
    @PostMapping("/login")
    public String login(UserLoginInfoVo  loginInfoVo, RedirectAttributes redirectAttributes, HttpSession session){
        R r = memberFeignService.loginCheck(loginInfoVo);
        if(r.getCode()==0){
            MemberResponseVo data = r.getData("data", new TypeReference<MemberResponseVo>() {
            });
            session.setAttribute(AuthServerConstant.LOGIN_USER,data);
            return "redirect:http://gulimall.com";
        }else {
            String msg = (String) r.get("msg");
            HashMap<String, String> errors = new HashMap<>();
            errors.put("msg",msg);
            redirectAttributes.addFlashAttribute("errors",errors);
            return "redirect:http://auth.gulimall.com/login.html";
        }
    }
}
